package dms.repository.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;

import dms.model.Classes;
import dms.model.Faculty;
import dms.model.School;
import dms.model.util.FindUtil;
import dms.model.util.PageIterator;
import dms.repository.SchoolRepository;
import dms.util.HibernateUtil;

/**
 * 
 * @author 李健
 *
 */

public class SchoolRepositoryHibernate implements SchoolRepository {

	private static Log log = LogFactory.getLog(SchoolRepositoryHibernate.class);
	
	@Override
	public Classes createClasses(Classes classes) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.save(classes);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return classes;
	}

	@Override
	public Faculty createFaculty(Faculty faculty) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.save(faculty);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return faculty;
	}

	@Override
	public School createSchool(School schoolInfo) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.save(schoolInfo);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return schoolInfo;
	}

	@Override
	public void deleteClassesById(Long id) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			Classes c = (Classes) session.load(Classes.class, id);
			session.delete(c);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}
	
	public void deleteClasses(List<Long> ids) {
		Session session = null;
		Transaction tx = null;
		
		String deleteQuery = "delete from Classes c where c.id in (ids) ";
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.createQuery(deleteQuery)
				   .setParameterList("ids", ids)
				   .executeUpdate();
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				if (session.isOpen()) {
					session.close();
				}
			}
		}
	}

	@Override
	public void deleteFacultyById(Long id) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			Faculty f = (Faculty) session.load(Faculty.class, id);
			session.delete(f);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
	}

	public void deleteFaculites(List<Long> ids) {
		Session session = null;
		Transaction tx = null;
		
		String deleteQuery = "delete from Faculty f where f.id in (ids) ";
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.createQuery(deleteQuery)
				   .setParameterList("ids", ids)
				   .executeUpdate();
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				if (session.isOpen()) {
					session.close();
				}
			}
		}
	}
	
	@Override
	public void deleteSchoolById(Long id) {
		Session session = null;
		Transaction tx = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			School s = (School) session.load(School.class, id);
			session.delete(s);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
	}
	
	public void deleteSchools(List<Long> ids) {
		Session session = null;
		Transaction tx = null;
		
		String deleteQuery = "delete from School s where s.id in (ids) ";
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.createQuery(deleteQuery)
				   .setParameterList("ids", ids)
				   .executeUpdate();
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				if (session.isOpen()) {
					session.close();
				}
			}
		}
	}

	@Override
	public PageIterator<School> findAllSchool(int start, int count) {
		Session session = null;
		Transaction tx = null;
		PageIterator<School> iter = null;
		List<School> list = null;
		Long allCount = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from School ";
			String findQuery = "select s from School s ";
			
			allCount = FindUtil.calculateAllCount(session, countQuery, null);
			list = FindUtil.getEntitiesByPage(session, findQuery, null, start, count);
			iter = new PageIterator<School>(list, allCount, start, count);
				
			tx.commit();
			
		} catch (Exception e) {
			log.error(e.toString());
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
		return iter;
	}

	@Override
	public PageIterator<Classes> findClassesByFaculty(Faculty faculty, int start, int count) {
		Session session = null;
		Transaction tx = null;
		PageIterator<Classes> iter = null;
		List<Classes> list = null;
		Long allCount = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from Classes c where c.faculty = ?  ";
			String findQuery = "select c from Classes c where c.faculty = ? ";
			Collection params = new ArrayList();
			params.add(faculty);
			
			allCount = FindUtil.calculateAllCount(session, countQuery, params);
			list = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
			iter = new PageIterator<Classes>(list, allCount, start, count);
				
			tx.commit();
			
		} catch (Exception e) {
			log.error(e.toString());
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
		return iter;
	}

	@Override
	public Classes findClassesById(Long id) {
		Session session = null;
		Transaction tx = null;
		Classes c = null;
		
		session = HibernateUtil.getSessionFactory().openSession();
		tx = session.beginTransaction();
		
		c = (Classes) session.load(Classes.class, id);
		//initialize property
		Hibernate.initialize(c);			
		return c;
	}

	@Override
	public Faculty findFacultyById(Long id) {
		Session session = null;
		Transaction tx = null;
		Faculty f = null;
		
		session = HibernateUtil.getSessionFactory().openSession();
		tx = session.beginTransaction();
		
		f = (Faculty) session.load(Faculty.class, id);
		//initialize property
		Hibernate.initialize(f);
	
		return f;
	}

	@Override
	public PageIterator<Faculty> findFacultyBySchool(School school, int start, int count) {
		Session session = null;
		Transaction tx = null;
		PageIterator<Faculty> iter = null;
		List<Faculty> list = null;
		Long allCount = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from Faculty f where f.school = ? ";
			String findQuery = "select f from Faculty f where f.school = ? ";
			Collection params = new ArrayList();
			params.add(school);
			
			allCount = FindUtil.calculateAllCount(session, countQuery, params);
			list = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
			iter = new PageIterator<Faculty>(list, allCount, start, count);
				
			tx.commit();
			
		} catch (Exception e) {
			log.error(e.toString());
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
		return iter;
	}

	@Override
	public School findSchoolById(Long id) {
		Session session = null;
		Transaction tx = null;
		School s = null;
	
		session = HibernateUtil.getSessionFactory().openSession();
		tx = session.beginTransaction();
		
		s = (School) session.load(School.class, id);
		//initialize property
		Hibernate.initialize(s);
			
		return s;
	}

	@Override
	public PageIterator<School> findSchoolByName(String name, int start, int count) {
		Session session = null;
		Transaction tx = null;
		List<School> s = null;
		PageIterator<School> iter = null;
		Long allCount = null;
	
		session = HibernateUtil.getSessionFactory().openSession();
		tx = session.beginTransaction();
		
		String countQuery = "select count(*) from School s where s.name like ?";
		String findQuery = "select s from School s where s.name like ? ";
		Collection params = new ArrayList();
		params.add("%" + name + "%");
		
		s = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
		allCount = FindUtil.calculateAllCount(session, countQuery, params);
		
		iter = new PageIterator<School>(s, allCount, start, count);

		return iter;
	}

	@Override
	public Classes updateClasses(Classes classes) {
		Session session = null;
		Transaction tx = null;
		Classes c = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			c = (Classes) session.merge(classes);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return c;
	}

	@Override
	public Faculty updateFaculty(Faculty faculty) {
		Session session = null;
		Transaction tx = null;
		Faculty f = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			f = (Faculty) session.merge(faculty);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return f;
	}

	@Override
	public School updateSchool(School schoolInfo) {
		Session session = null;
		Transaction tx = null;
		School s = null;
		
		try {
			
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			s = (School) session.merge(schoolInfo);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return s;
	}

	@Override
	public PageIterator<Classes> findClassesByName(String name, int start, int count) {
		Session session = null;
		Transaction tx = null;
		List<Classes> c = null;
		PageIterator<Classes> iter = null;
		Long allCount = null;
		
		session = HibernateUtil.getSessionFactory().openSession();
		tx = session.beginTransaction();
		
		String countQuery = "select count(*) from Classes c where c.name like ?";
		String findQuery = "select c from Classes c where s.name like ?";
		Collection params = new ArrayList();
		params.add("%" + name + "%");
		
		c = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
		allCount = FindUtil.calculateAllCount(session, countQuery, params);
		
		iter = new PageIterator<Classes>(c, allCount, start, count);
			
		return iter;
	}


}
